﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Media3D;
using System.ComponentModel;

using ObjectEditor;
using ObjectEditor.Display3D;
using ObjectEditor.Editor;
using Microsoft.Win32;
using Microsoft.Practices.Unity;

using EQEmu.Maps.Display3D;
using EQEmu.Maps;

namespace EQEmu.MapsPlugin
{
    internal class MapVisual3D : ModelVisual3D
    {

    }

    public class MapsRibbonTabViewModel : ViewModel, IWorldModel3DProvider, IObjectEditor, IDisposable
    {
        private DelegateCommand _openFileCommand;
        private string _currentFileName = String.Empty;
        private Transform3D _transform;

        private Map _map;
        private MapDisplay3D _map3d;
        private ModelVisual3D _modelVisual;

        public event EventHandler<ModelChangedEventArgs> ModelChanged;       
 
        #pragma warning disable 67
        public event EventHandler<CameraChangeEventArgs> RequestCameraChange;
        #pragma warning restore 67


        protected void OnModelChanged()
        {
            var e = ModelChanged;
            if (e != null)
            {
                e(this, new ModelChangedEventArgs());
            }
        }

        public DelegateCommand OpenFileCommand
        {
            get
            {
                if (_openFileCommand == null)
                {
                    _openFileCommand = new DelegateCommand(x =>
                    {
                        var od = new OpenFileDialog();
                        od.Filter = MapFileFilter;
                        if ((bool)od.ShowDialog())
                        {
                            try
                            {
                                MapData = Map.LoadFile(od.FileName);
                                CurrentFileName = System.IO.Path.GetFileName(od.FileName);
                            }
                            catch (Exception e)
                            {
                                System.Windows.MessageBox.Show("Could not open map file:" + od.FileName + "," + e.Message);
                            }
                        }
                    },
                    y =>
                    {
                        return true;
                    });
                }
                return _openFileCommand;
            }
        }

        public string MapFileExtension
        {
            get { return "map"; }
        }

        public string MapFileFilter
        {
            get
            {
                return String.Format("Maps Files (.{0})|*.{0}|All Files (*.*)|*.*", MapFileExtension);
            }
        }

        public string CurrentFileName
        {
            get { return _currentFileName; }
            set
            {
                _currentFileName = value;
                OnPropertyChanged("CurrentFileName");
            }
        }

        public Map MapData
        {
            get { return _map; }
            private set
            {
                if (_map3d != null)
                {
                    _map3d.Dispose();
                }

                _map = value;
                _map3d = new MapDisplay3D(_map);

                Model3D = new MapVisual3D()
                {
                    Content = _map3d.Model,
                    Transform = Transform3D
                };
            }
        }

        [Dependency("EQEmu.Transform")]
        public Transform3D Transform3D
        {
            get { return _transform; }
            set
            {
                _transform = value;
            }
        }

        public ModelVisual3D Model3D
        {
            get { return _modelVisual; }
            private set
            {
                if (_modelVisual != null)
                {
                    _modelVisual.Children.Clear();
                }

                _modelVisual = value;
                OnPropertyChanged("Model3D");
                OnModelChanged();
            }
        }

        public void UserClicked(Point3D point, AppInformation info)
        {
            return;
        }

        public event EventHandler<ObjectSelectedEventArgs> ObjectSelected;

        protected void OnObjectSelected(INotifyPropertyChanged value)
        {
            var e = ObjectSelected;
            if (e != null)
            {
                e(this, new ObjectSelectedEventArgs(value));
            }
        }

        protected virtual void Dispose(bool disposeAll)
        {
            if (_map3d != null)
            {
                _map3d.Dispose();
            }
        }

        public void Dispose()
        {
            Dispose(true);
        }


        public void ConstrainView(ViewConstraints constraints)
        {
            if (_map3d == null) return;

            _map3d.UpdateView(new EQEmu.Display3D.ViewConstraints()
            {
                MaxX = constraints.MaxX,
                MaxY = constraints.MaxY,
                MaxZ = constraints.MaxZ,
                MinX = constraints.MinX,
                MinY = constraints.MinY,
                MinZ = constraints.MinZ
            });
        }        
    }
}
